package cz.muni.fi.pa165.sme.web.panels.user;

import java.util.Arrays;
import java.util.Date;

import cz.muni.fi.pa165.sme.api.UserService;
import cz.muni.fi.pa165.sme.api.enumeration.UserRoleTO;
import cz.muni.fi.pa165.sme.api.to.UserTO;
import cz.muni.fi.pa165.sme.web.common.ErrorBehavior;
import cz.muni.fi.pa165.sme.web.common.LoginValidator;
import cz.muni.fi.pa165.sme.web.fo.SexFO;
import cz.muni.fi.pa165.sme.web.fo.UserFO;
import cz.muni.fi.pa165.sme.web.pages.LoginPage;
import org.apache.wicket.extensions.yui.calendar.DateField;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.form.NumberTextField;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.util.visit.IVisit;
import org.apache.wicket.util.visit.IVisitor;
import org.apache.wicket.validation.validator.RangeValidator;
import org.apache.wicket.validation.validator.StringValidator;
import org.springframework.core.convert.ConversionService;

/** @author jirankova */
public class RegistrationForm extends Panel {

	private static final UserRoleTO defaultRole = UserRoleTO.USER;

	@SpringBean
	private UserService userService;

	@SpringBean(name = "conversionServiceFe")
	private ConversionService conversionService;


	public RegistrationForm(final String id, final IModel<UserFO> model) {
		super(id, model);

		final FormComponent<String> login = new TextField<String>("login");
		login.add(new LoginValidator(userService));
		login.setRequired(true);

		final FormComponent<String> password = new TextField<String>("password");
		password.add(new StringValidator.MinimumLengthValidator(6));
		password.setRequired(true);

		final FormComponent<String> firstName = new TextField<String>("firstName");
		firstName.setRequired(true);

		final FormComponent<String> lastName = new TextField<String>("lastName");
		lastName.setRequired(true);


		final FormComponent<SexFO> sex = new DropDownChoice<SexFO>("sex",
				Arrays.asList(SexFO.values()), new IChoiceRenderer<SexFO>() {
			@Override
			public Object getDisplayValue(final SexFO sexFO) {
				return getLocalizer().getString(sexFO.getName(), RegistrationForm.this);
			}

			@Override
			public String getIdValue(final SexFO sexFO, final int index) {
				return sexFO.name();
			}
		});
		sex.setRequired(true);

		final FormComponent<Date> dateOfBirth = new DateField("dateOfBirth");

		final FormComponent<Float> weight = new NumberTextField<Float>("weight").add(new RangeValidator<Float>(0f, 300f));

		final FormComponent<Integer> height = new NumberTextField<Integer>("height").add(new RangeValidator<Integer>(0, 300));

		final Form<UserFO> userForm = new Form<UserFO>("registrationForm", model) {
			@Override
			protected void onSubmit() {
				super.onSubmit();

				final UserFO userFO = model.getObject();
				final UserTO userTO = conversionService.convert(userFO, UserTO.class);
				userTO.setRoleTO(defaultRole);
				userTO.setPassword(org.apache.commons.codec.digest.DigestUtils.sha256Hex(userFO.getPassword()));

				//create a new user
				userService.createUser(userTO);
				setResponsePage(LoginPage.class);
			}
		};

		userForm.add(login);
		userForm.add(password);
		userForm.add(firstName);
		userForm.add(lastName);
		userForm.add(sex);
		userForm.add(dateOfBirth);
		userForm.add(weight);
		userForm.add(height);

		add(userForm);

		userForm.visitChildren(FormComponent.class, new IVisitor<FormComponent<?>, IVisit<Void>>() {
			@Override
			public void component(final FormComponent<?> object, final IVisit<IVisit<Void>> visit) {
				object.add(new ErrorBehavior());
				visit.dontGoDeeper();
			}
		});

		final FeedbackPanel feedbackPanel = new FeedbackPanel("feedbackPanel");
		feedbackPanel.setOutputMarkupId(true);
		add(feedbackPanel);
	}
}
